# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: helpers\encryption\text_aes_cbc.py
__author__ = "Attila Gerendi (Sanyi)"
import base64, binascii
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from helpers.encryption.exceptions import InvalidKey, InvalidData
from helpers.encryption.openssl import openssl_kdf


def decrypt(data, secret, b64=True, default_encoding="utf-8"):
    try:
        data = data.encode(default_encoding)
    except AttributeError:
        pass

    try:
        secret = secret.encode(default_encoding)
    except AttributeError:
        pass

    if b64:
        try:
            data = base64.b64decode(data)
        except binascii.Error:
            raise InvalidData("b64decode error")

        if data[0:8] != b"Salted__":
            raise InvalidData("prefix not found")
        salt = data[8:16]
        if len(salt) < 8:
            raise InvalidData("invalid header length")
        data = data[16:]
        mat = (b"").join([x for x in openssl_kdf(48, secret, salt)])
        key = mat[0:32]
        iv = mat[32:48]
        dec = AES.new(key, AES.MODE_CBC, iv)
        decrypted = dec.decrypt(data)
        padding_length = decrypted[-1]
        if bytes((padding_length,) * padding_length) != decrypted[-padding_length:]:
            raise InvalidKey()
        return decrypted[:-padding_length]


def encrypt(data, secret, b64=True, default_encoding="utf-8"):
    try:
        data = data.encode(default_encoding)
    except AttributeError:
        pass

    try:
        secret = secret.encode(default_encoding)
    except AttributeError:
        pass

    salt = get_random_bytes(8)
    encoded = [b"Salted__", salt]
    mat = (b"").join([x for x in openssl_kdf(48, secret, salt)])
    key = mat[0:32]
    iv = mat[32:48]
    padding_length = 16 - len(data) % 16
    padding = bytes((padding_length,) * padding_length)
    encoder = AES.new(key, AES.MODE_CBC, iv)
    encoded.append(encoder.encrypt(data + padding))
    result = (b"").join(encoded)
    if b64:
        return base64.b64encode(result).decode(default_encoding)
    else:
        return result


if __name__ == "__main__":
    p = "test"
    v = "some string"
    e = encrypt(v, p)
    print(decrypt(e, p))
